package com.tedu.api.list;

import org.junit.Test;

import java.util.*;

/**
 * Collection顶级集合容器
 * List集合【接口】 继承与Collection【接口】
 * List集合：存储重复并且有序的元素
 * 注意：List集合类似数组，有些方法与数组使用一致
 * List集合【接口】
 * java.util.ArrayList:数组实现【常用】
 * java.util.LinkedList：链表实现
 * 以上两个类使用方法完全一致！
 *
 */
public class ListAPI {
    /**List接口--提高get方法，可以被ArrayList类重写
     * get(int index)      返回值：E
     */
@Test
public void testGet(){
        //多态方式：父类引用指向子类对象【常用：调父、子方法，方法相同：重写】
        //重写调用子类方法，如果子类没有重写，调用父类的方法
        /*  List<String> list=new ArrayList<>();
        list.get(0);  //重写：调用子类的get方法
        //直接创建实现类对象:调用ArrayList方法
        ArrayList<String> al=new ArrayList<>();
        al.get(0);*/
List<String> list=new ArrayList<>();
list.add("西游记"); list.add("水浒传");list.add("红楼梦");
System.out.println("打印List集合："+list);
        //获取下标：1
String index=list.get(1);
System.out.println("取出集合元素："+index);
        //遍历集合内容---普通for
for(int i=0;i<list.size();i++){ //i  下标  0  1  2
index=list.get(i);
System.out.println("获取集合全部元素："+index);
        }
    }
    /**List接口下方法
     * 添加、替换、移除
     * add(int index,E e)方法     返回值：void   重载方法
     * 作用：将给定元素插入到指定位置
     * set(int index,E e)方法     返回值：E
     * 作用：将给定元素设置到指定的位置上 【替换】
     * remove(int index)方法       返回值：E     重载方法
     * Collection接口  remove使用方法一致，用元素删除
     * List接口remove方法，用下标删除
     * --------总结：以上三个方法都可以直接操作集合
     */
    @Test
    public void testASR(){
        List<String> list=new ArrayList<>();
        list.add("one");list.add("two");list.add("three");
    //需求：在集合  two元素前  添加  "2"
        list.add(1,"2");
        System.out.println("插入元素的集合："+list);
    //需求：在集合 2 元素  将 2 元素替换成 二
        list.set(1,"二");
        System.out.println("修改元素的集合："+list);
    //需求：删除集合中”二“的元素
        list.remove("二");  //Collection接口remove，通过元素，删元素
        list.remove(1);  //List接口remove,通过下标，删元素
        System.out.println(list);
    }


    /**List提供可以获取子集方法     返回值：List<E>[Object对象]
     * subList(int start,int end)   口诀：含头不含尾
     * 作用：截取集合中范围内的子集
     */
    @Test
    public void testSubList(){
    //创建集合，指定类型Integer
        List<Integer>list=new ArrayList<>();
    //需求：添加10个元素，元素数：0~9个数值
        for (int i=0;i<10;i++){ //所有集合重写父集的方法！
            list.add(i);//add()添加--重写：Collection-add的方法
    }
    //打印集合
        System.out.println("增加元素后的集合："+list);
    //需求：需要获取子集，范围：3~8的元素,分页操作：获取子集合
        List<Integer> list1=list.subList(3,9);
    //打印子集合
        System.out.println("获取子集："+list1);
        System.out.println("打印集合："+list);
    //练习：截取list 2~7的元素，子集扩大10倍,提醒：set方法
     List<Integer> list2=list.subList(2,8);
     for(int i=0;i<list2.size();i++){//获取子集下标
         //设置子集扩大10倍
         list2.set(i,list2.get(i)*10);
         //   set(i: 0~4  下标
         //   list2.get(0~4):获取对应元素 *10)
     }
        System.out.println("输出list2子集集合元素："+list2);
    //练习2：删除list集合元素中：1~7的元素，提醒：子集、清除
 List<Integer> listRem=list.subList(1,8);
 listRem.clear();
        System.out.println("删除list[2~7]元素,最终集合："+list);
        //总结：获取子集，打印子集没有操作
        //清空子集：原来集合移除部分子集

    }
    /**
     * 数组转集合操作
     * Array工具类：提供静态方法asList(数组引用)
     *                       asList(数组引用):将数组转换为集合
     *注意：UnsupportedOperationException异常问题
     */

    @Test
    public void testArray(){
        //创建字符串静态数组
        String[] array={"十一","元旦","寒假"};
//将数组转换为集合        -------软件更新
        List<String> list= Arrays.asList(array);
//需求：将list集合中"元旦"改成"除夕"
        list.set(1,"除夕");
        System.out.println("数值转集合："+list);
           //需求：增强for，数组添加元素【add方法 add("节日")】
        for(String str:array){
            /**
             * UnsupportedOperationException
             * 不支持操作系统异常
             * 因为遍历数组，进行集合操作，不支持操作异常
             */
            //list.add("节日");
        }
        /**
         * List构造器使用:传入有参构造器【类型：其他集合，功能：addAll】
         * 创建集合 List<String> list=new ArrayList(集合引用);
         */
        List<String> lists=new ArrayList<>();
        //集合构造器参数：集合引用---lists集合元素添加至listes集合中
        //替代：addAll方法    操作：并集
        List<String> listes=new ArrayList<>();
    }
    /**
     * 集合排序
     * Collections 工具类
     * 静态方法：sort()  排序【默认升序】---实现List接口排序功能
     *
     *
     * java.util.Random：伪随机数类
     * nextInt(数值)  功能：返回一个数值内伪随机数
     * 导入包问题：通过导入包方式
     *          如果类存在于util工具包下，例如：import java.util.*
     *          类最上方： import java.util.Random
     *                   import java.util.List
     *                   import java.util.ArrayList
     * 需求：创建集合随机生成10个元素【100以内伪随机数】
     */
    @Test
    public void testRandom(){
        List<Integer> list=new ArrayList<>();
        //创建随机数对象
        Random random=new Random();
        //给list集合添加10个元素【100以内随机数】
        for(int i=0;i<10;i++){
            list.add(random.nextInt(100)); //100以内随机数
        }
        System.out.println("list集合:"+list);
        //将list集合元素进行排序
        Collections.sort(list);
        System.out.println("排序后List集合："+list);
    }

    /**
     * 集合排序
     * Collections 工具类
     *
     * 面试题：Collection和Collections的区别？
     *       Collection所有集合的顶级接口，约定所有集合共有方法！
     *       Collections工具类，提供集合操作方法！
     *
     * 静态方法sort(集合引用，比较器引用)  功能：按照比较器约定规范排序
     * Comparator  比较器
     * 需求：集合存汉字---按照要求排序【比较器】
     */
    @Test
    public void testSort(){
        List<String> list=new ArrayList<>();
        list.add("阿西吧~");
        list.add("搜嘎斯内~");
        list.add("哟西!");
        Collections.sort(list);  //排序：针对数值
        System.out.println("排序后集合："+list);
        //需求：按照文字长短进行排序  重载sort方法
        //创建比较器接口对象 【匿名内部类】
        //比较器对象内部提供方法：针对集合排序操作【交换规则】
        Comparator<String> com=new Comparator<String>() {
        //定义比较器规则：按照汉字长度排序---交换操作compare方法完成
        public int compare(String o1, String o2) {
        return o1.length()-o2.length();
                /**
                 * o1.length()  获取第一个字符串长度
                 * o2.length()  获取第二个字符串长度
                 * 汉字短移动靠前
                 * 返回值：  大于0       假设：4-2    交换
                 *          小于0      假设：3-4    不交换
                 *          等于0      假设：2-2    不变
                 */
        }
        };
        //比较器：规定文字短在前规则，使用比较器规则
        Collections.sort(list,com);
        System.out.println("按照文字长短进行集合排序："+list);

    }

    /**
     * 总结：List集合
     * List接口集合   是Collection容器接口  的子接口
     * List子接口---无法实例化---实现类：ArrayList、LinkedList、Vector
     * 使用情况：保存一组数据，有序情况，采用List集合
     * List子接口方法就是ArrayList的方法！因为ArrayList重写List所有方法
     */
    @Test
    public void testArrayList(){
        //下述方法创建对象：【常用方法：父子级对象的方法   多态：方法一致，
        //                         调用父类的方法-----执行父类方法
        //                         调用子类的方法-----与父类方法名、参数完全一致，执行子类的重写方法 】
        List<String> list=new ArrayList<>();
        list.add("张三"); list.add("李四"); list.add("王五");
        //由List[ArrayList]保存集合，内存创建状态

     /*   //调取几个方法
        list.add("张三");list.set(0,"王五");
        //下述方法创建对象：只调用ArrayList的方法
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("李四");arrayList.set(0,"赵六");*/
    }
}